package ws

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"myginproject/internal/models"
	"net/http"
	"strings"
	"sync"
	"time"
	"unicode/utf8"

	"github.com/go-redis/redis/v8"
	"github.com/google/uuid"
	"github.com/gorilla/websocket"
	"gorm.io/gorm"
)

// WebSocket 升级器配置
var Upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return true // 生产环境应限制来源
	},
}

// Client 表示一个 WebSocket 客户端连接
type Client struct {
	ID         string          // 客户端唯一ID
	Conn       *websocket.Conn // WebSocket 连接
	Send       chan []byte     // 发送消息的通道
	User       *models.WsUser  // 用户信息
	Groups     map[string]bool // 客户端加入的群组
	LastActive time.Time       // 最后活跃时间
	mu         sync.RWMutex    // 读写锁
	hub        *Hub            // 所属 Hub
}

// Hub 管理所有 WebSocket 连接和群组
type Hub struct {
	clients    map[*Client]bool            // 所有客户端连接
	groups     map[string]map[*Client]bool // 群组映射表
	Broadcast  chan *models.WsMessage      // 广播消息通道
	register   chan *Client                // 注册通道
	unregister chan *Client                // 注销通道
	db         *gorm.DB                    // 数据库实例
	redis      *redis.Client               // Redis 客户端
	mu         sync.RWMutex                // 读写锁
}

// 在 Hub 结构体定义中添加这个方法
func (h *Hub) GetRedis() *redis.Client {
	return h.redis
}

// NewHub 创建新的 Hub 实例
func NewHub(db *gorm.DB, redisClient *redis.Client) *Hub {
	return &Hub{
		clients:    make(map[*Client]bool),
		groups:     make(map[string]map[*Client]bool),
		Broadcast:  make(chan *models.WsMessage, 1024),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		db:         db,
		redis:      redisClient,
	}
}

// Run 启动 Hub 的事件循环
func (h *Hub) Run() {
	for {
		select {
		case client := <-h.register:
			h.handleRegister(client)
		case client := <-h.unregister:
			h.handleUnregister(client)
		case message := <-h.Broadcast:
			h.handleBroadcast(message)
		}
	}
}

// HandleGroupChat 处理群聊 WebSocket 连接
func (h *Hub) HandleGroupChat(conn *websocket.Conn, user *models.WsUser, groupID string) *Client {
	// ctx := context.Background()

	// // 检查群组是否存在
	// exists, err := h.redis.Exists(ctx, "WsGroup:"+groupID).Result()
	// fmt.Println("检查群组是否存在Redis 查询结果：", exists)
	// if err != nil {
	// 	log.Printf("Redis 查询错误: %v", err)
	// 	conn.Close()
	// 	return nil
	// }

	// // 如果群组不存在，
	// if exists == 0 {
	// 	log.Printf("群组不存在: %v", err)
	// 	conn.Close()
	// 	return nil
	// }

	// 创建客户端实例
	client := &Client{
		ID:         uuid.New().String(),
		Conn:       conn,
		Send:       make(chan []byte, 256),
		User:       user,
		Groups:     make(map[string]bool),
		LastActive: time.Now(),
		hub:        h,
	}

	// 将客户端添加到群组
	h.mu.Lock()
	if _, exists := h.groups[groupID]; !exists {
		h.groups[groupID] = make(map[*Client]bool)
	}
	h.groups[groupID][client] = true
	h.mu.Unlock()

	client.Groups[groupID] = true

	// 注册客户端
	h.register <- client

	// 启动读写协程
	go client.writePump()
	go client.readPump()

	// 发送加入通知
	h.Broadcast <- &models.WsMessage{
		MsgID:     uuid.New().String(),
		GroupID:   groupID,
		SenderID:  user.ID,
		Sender:    user.Name,
		Avatar:    user.Avatar,
		Content:   user.Name + " 加入了群聊",
		Event:     "system",
		Timestamp: time.Now(),
	}

	return client
}

// handleRegister 处理客户端注册
func (h *Hub) handleRegister(client *Client) {
	h.mu.Lock()
	defer h.mu.Unlock()

	h.clients[client] = true
	log.Printf("客户端注册: %s (%s)", client.ID, client.User.Name)
}

// handleUnregister 处理客户端注销
func (h *Hub) handleUnregister(client *Client) {
	h.mu.Lock()
	defer h.mu.Unlock()

	if _, ok := h.clients[client]; ok {
		// 从所有群组中移除
		for groupID := range client.Groups {
			if group, exists := h.groups[groupID]; exists {
				delete(group, client)
				if len(group) == 0 {
					delete(h.groups, groupID)
				}
			}
		}

		// 关闭通道并删除客户端
		close(client.Send)
		delete(h.clients, client)
		log.Printf("客户端注销: %s", client.ID)
	}
}

// handleBroadcast 处理消息广播
func (h *Hub) handleBroadcast(msg *models.WsMessage) {
	h.mu.RLock()
	defer h.mu.RUnlock()
	msgBytes, err := json.Marshal(msg)
	if err != nil {
		log.Printf("JSON marshal error: %v", err)
		return
	}
	// 生成消息ID（如果未设置）
	if msg.MsgID == "" {
		msg.MsgID = uuid.New().String()
	}
	log.Printf("Broadcasting message (raw): %s", string(msgBytes)) // 调试日志
	// 查找目标群组
	if group, exists := h.groups[msg.GroupID]; exists {
		// 序列化消息
		rawMsg, err := json.Marshal(msg)
		if err != nil {
			log.Printf("消息序列化失败: %v", err)
			return
		}

		// 向群组内所有客户端发送消息
		for client := range group {
			select {
			case client.Send <- rawMsg:
				client.mu.Lock()
				client.LastActive = time.Now()
				client.mu.Unlock()
			default:
				// 发送失败则注销客户端
				h.unregister <- client
			}
		}
	}
}

// writePump 处理消息写入
func (c *Client) writePump() {
	defer func() {
		c.hub.unregister <- c
		c.Conn.Close()
	}()

	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				// 通道关闭，发送关闭消息
				c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}

			c.mu.Lock()
			err := c.Conn.WriteMessage(websocket.TextMessage, message)
			c.LastActive = time.Now()
			c.mu.Unlock()

			if err != nil {
				return
			}
		}
	}
}

// readPump 处理消息读取
func (c *Client) readPump() {
	defer func() {
		c.hub.unregister <- c
		c.Conn.Close()
	}()

	for {
		// 读取消息
		messageType, rawMsg, err := c.Conn.ReadMessage()
		if err != nil {
			break
		}

		// 只处理文本消息类型
		if messageType != websocket.TextMessage {
			continue
		}

		// 打印原始消息用于调试
		fmt.Printf("Raw message received: %s\n", string(rawMsg))

		// 解析消息
		var msg models.WsMessage
		if err := json.Unmarshal(rawMsg, &msg); err != nil {
			log.Printf("JSON unmarshal error: %v, raw: %s", err, string(rawMsg))
			continue
		}

		// 修复可能的编码问题
		msg.Content = fixEncoding(msg.Content)
		msg.Sender = fixEncoding(c.User.Name)

		// 设置发送者信息
		msg.SenderID = c.User.ID
		msg.Avatar = c.User.Avatar
		msg.Timestamp = time.Now()

		// 设置默认事件类型
		if msg.Event == "" {
			msg.Event = "message"
		}

		// 处理特殊事件
		switch msg.Event {
		case "join":
			// 加入群组（已通过URL参数处理）
		case "leave":
			// 离开群组
			c.hub.mu.Lock()
			if group, exists := c.hub.groups[msg.GroupID]; exists {
				delete(group, c)
				delete(c.Groups, msg.GroupID)
				if len(group) == 0 {
					delete(c.hub.groups, msg.GroupID)
				}
			}
			c.hub.mu.Unlock()
		default:
			// 打印处理后的消息用于调试
			fmt.Printf("Processed message: %+v\n", msg)

			// 广播普通消息
			c.hub.Broadcast <- &msg
		}
	}
}

// 修改后的 fixEncoding 函数
func fixEncoding(s string) string {
	// 如果已经是有效的UTF-8，直接返回
	if utf8.ValidString(s) {
		return s
	}

	// 尝试将可能的乱码转换为UTF-8
	if isLikelyMisinterpretedUTF8(s) {
		// 假设是ISO-8859-1被错误解释为UTF-8
		return convertISO88591ToUTF8(s)
	}

	// 其他情况返回原始字符串
	return s
}

func isLikelyMisinterpretedUTF8(s string) bool {
	// 检查是否包含典型的错误编码字符
	return strings.Contains(s, "å") || strings.Contains(s, "æ") || strings.Contains(s, "ø")
}

func convertISO88591ToUTF8(s string) string {
	var buf bytes.Buffer
	for i := 0; i < len(s); i++ {
		r := rune(s[i])
		if r < utf8.RuneSelf {
			buf.WriteByte(byte(r))
		} else {
			buf.WriteRune(r)
		}
	}
	return buf.String()
}
